package com.example.k8s.hello.service.common.config;

import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import com.example.k8s.hello.common.bean.RestResponse;
import com.example.k8s.hello.common.exception.ApiExEnum;
import com.example.k8s.hello.common.exception.BizException;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.RestClientException;

import java.util.stream.Collectors;

/**
 * 异常处理器
 *
 * @author Mark sunlightcs@gmail.com
 */
@Slf4j
@RestControllerAdvice("com.example")
public class ExceptionHandlerConfig {

	/**
	 * 处理自定义异常
	 */
	@ExceptionHandler(BizException.class)
	public RestResponse handleRRException(BizException ex){
		log.error("自定义异常", ex);
		return RestResponse.error(ex);
	}

	/**
	 * 处理接口调用异常
	 */
	@ExceptionHandler(RestClientException.class)
	public RestResponse handleRCRException(RestClientException ex){
		log.error("调用服务出错", ex);
		return RestResponse.error(ApiExEnum.C0001, ex);
	}

	/**
	 * 参数校验异常
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public RestResponse handleRRException(MethodArgumentNotValidException ex){
		log.debug("参数校验异常", ex);
		String msg = ex.getBindingResult().getFieldErrors().stream()
				.map(fieldError -> fieldError.getField() + fieldError.getDefaultMessage())
				.collect(Collectors.joining("; "));

		return RestResponse.error(ApiExEnum.A0010.name(), msg);
	}

	@ExceptionHandler(SaTokenException.class)
	public RestResponse onSaError(SaTokenException ex, HttpServletResponse response) {
		if (ex.getCode() == SaErrorCode.CODE_11011) {
			response.setStatus(HttpStatus.UNAUTHORIZED.value());
			return RestResponse.error(ApiExEnum.A0004);

		} else if (ex.getCode() == SaErrorCode.CODE_11012) {
			response.setStatus(HttpStatus.UNAUTHORIZED.value());
			return RestResponse.error(ApiExEnum.A0005);

		} else if (ex.getCode() == SaErrorCode.CODE_11051) {
			response.setStatus(HttpStatus.FORBIDDEN.value());
			return RestResponse.error(ApiExEnum.A0006);
		}

		return RestResponse.error(ex);
	}

	@ExceptionHandler(Exception.class)
	public RestResponse handleException(Exception ex){
		log.error("Internal error", ex);
		return RestResponse.error(ex);
	}
}
